home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / CMPLTPAS / STICK.ASM < prev    next >
Assembly Source File  |  1988-08-01  |  6KB  |  147 lines

  1. ;======================================================================
  2. ;
  3. ;    S T I C K  -  Assembly language joystick input for Turbo Pascal
  4. ;
  5. ;======================================================================
  6. ;
  7. ;    by Jeff Duntemann     12 February 1988
  8. ;      with thanks to Ted Mirecki for additional insights
  9. ;
  10. ;     From: COMPLETE TURBO PASCAL 5.0  by Jeff Duntemann
  11. ;    Scott, Foresman & Co., Inc. 1988   ISBN 0-673-38355-5
  12. ;
  13. ; STICK is written to be called from Turbo Pascal V4.0 using the
  14. ; {$L}/EXTERNAL procedure convention.
  15. ;
  16. ; Declare the procedure itself as an external using this declaration:
  17. ;
  18. ;    {$L STICK}
  19. ;    PROCEDURE STICK(StickNumber : Integer VAR X,Y : Integer);
  20. ;                                          EXTERNAL;
  21. ;
  22. ; StickNumber specifies which joystick to read from, and the X and Y
  23. ; parameters return integers proportional to the joystick's position
  24. ; at the moment the stick is sampled.  These integers will vary from
  25. ; stick to stick depending on the resistance of the potentiometers
  26. ; used within the stick, but will typically from from 3 to 150.
  27. ;
  28. ; The IBM standard game controller board consists of two pairs of
  29. ; one-shots, which output a pulse when triggered by an I/O write to
  30. ; I/O port $201.  The length of this pulse is determined by an RC
  31. ; time constant circuit the resistance portion of which is the
  32. ; potentiometer in the joystick.  As the handle is moved around, the
  33. ; two potentiometers (one for X, one for Y) run up and back, changing
  34. ; resistance as they go.
  35. ;
  36. ; To read one of the two joysticks, a dummy value (which may be anything
  37. ; at all) is written to I/O port $201.  Port $201 must then be polled
  38. ; continuously, incrementing a register at each polling event.  When
  39. ; the bit corresponding to that stick's X or Y coordinate changes state,
  40. ; the count in the register is returned as that coordinate value at the
  41. ; time the stick was sampled.
  42. ;
  43. ; Here is a map of the joystick bits as returned by port $201:
  44. ;
  45. ;     |7 6 5 4 3 2 1 0|
  46. ;              | | | |
  47. ;              | | | - - - - - - -> X coordinate, joystick #1
  48. ;              | | - - - - - - - -> Y coordinate, joystick #1
  49. ;              | - - - - - - - - -> X coordinate, joystick #2
  50. ;              - - - - - - - - - -> Y coordinate, joystick #2
  51. ;
  52. ; One thing to keep in mind is that a bit goes LOW when sampled, and
  53. ; you must test for a HIGH on that bit to indicate that the one-shot has
  54. ; timed out.
  55. ;
  56. ;
  57. ; To reassemble/relink STICK:
  58. ;-------------------------------------
  59. ; Assemble this file with MASM.  "C>MASM STICK;"
  60. ;
  61. ;
  62. ; This structure defines the layout of parameters on the stack.
  63. ;
  64. ONSTACK   STRUC
  65. OLDBP     DW   ?               ;TOP OF STACK
  66. RETADDR   DD   ?               ;FAR RETURN ADDRESS
  67. YADDR     DD   ?               ;FAR ADDRESS OF X VALUE
  68. XADDR     DD   ?               ;FAR ADDRESS OF Y VALUE
  69. STIK_NO   DW   ?               ;STICK NUMBER
  70. ONSTACK   ENDS
  71.  
  72. CODE      SEGMENT PUBLIC
  73.           ASSUME  CS:CODE
  74.           PUBLIC  STICK
  75.  
  76. ;  EQUATES FOR ONE-SHOT BITS FOR STICKS 1 & 2
  77.  
  78. STICK_X   EQU      1
  79. STICK_Y   EQU      2
  80.  
  81.  
  82. STICK     PROC    FAR
  83.           PUSH    BP          ;SAVE CALLER'S BP
  84.           MOV     BP,SP       ;STACK POINTER BECOMES NEW BP
  85.           PUSH    DS
  86.  
  87. ;  GET THE X AXIS VALUE FIRST
  88.  
  89.           MOV     AH,STICK_X       ; MOVE IN THE X TEST BIT
  90.           CMP     [BP].STIK_NO,2   ; SEE IF WE'RE TESTING STICK #1 OR #2
  91.           JNE     TEST_X
  92.           SHL     AH,1        ; SHIFT BIT NUMBERS 2 LEFT FOR STICK #2
  93.           SHL     AH,1
  94. TEST_X:   MOV     AL,1        ; INITIALIZE OUTPUT VALUE
  95.           MOV     DX,201H     ; SET PORT ADDRESS
  96.           MOV     BX,0        ; AND KEEPING THE RUNUP COUNT IN BX
  97.           MOV     CX,BX       ; LOOP 64K TIMES MAX
  98.           OUT     DX,AL       ; TRIGGER THE ONE-SHOTS
  99. AGAIN_X:  IN      AL,DX       ; READ THE ONE-SHOT BITS
  100.           TEST    AL,AH       ; TEST FOR A HIGH BIT 0
  101.           JE      DELAY       ; WE'RE DONE IF BIT 0 IS HIGH
  102.           INC     BX          ; OTHERWISE INCREMENT BX AND LOOP AGAIN
  103.           LOOP    AGAIN_X
  104.           MOV     BX,-1       ; SET X=-1 IF NO RESPONSE
  105.  
  106. ;  DELAY HERE TO LET THE OTHER THREE PULSES MAX OUT
  107.  
  108. DELAY:    MOV     CX,512
  109. WAIT:     LOOP    WAIT
  110.  
  111. ;  NOW WE GET THE Y AXIS VALUE
  112.  
  113.           MOV     AH,STICK_Y       ; MOVE IN THE Y TEST BIT
  114.           CMP     [BP].STIK_NO,2   ; SEE IF WE'RE TESTING STICK #1 OR #2
  115.           JNE     TEST_Y
  116.           SHL     AH,1        ; SHIFT BIT NUMBERS 2 LEFT FOR STICK #2
  117.           SHL     AH,1
  118.  
  119. TEST_Y:   MOV     SI,0        ; KEEP THE RUNUP COUNT FOR Y IN SI
  120.           MOV     CX,SI       ; SET LOOP LIMIT TO 64K
  121.           OUT     DX,AL       ; FIRE THE ONE-SHOTS AGAIN
  122. AGAIN_Y:  IN      AL,DX       ; READ THE ONE-SHOT BITS
  123.           TEST    AL,AH       ; TEST FOR A HIGH BIT 1
  124.           JE      DONE        ; WE'RE DONE IF BIT 1 IS HIGH
  125.           INC     SI          ; OTHERWISE INCREMENT SI AND LOOP AGAIN
  126.           LOOP    AGAIN_Y
  127.           MOV     SI,-1       ; SET Y=-1 IF NO RESPONSE
  128.  
  129. ;  MOVE RETURN VALUES FROM REGISTERS INTO VAR PARAMETERS X & Y
  130.  
  131. DONE:     LDS     DI,[BP].XADDR          ;ADDR OF X INTO DS:DI
  132.           MOV     [DI],BX                ;X VALUE FROM BX TO DS:DI
  133.           LDS     DI,[BP].YADDR          ;DITTO FOR Y VALUE FROM SI
  134.           MOV     [DI],SI
  135.  
  136. ;  IT'S OVER...NOW CLEAN UP THE STACK AND LEAVE
  137.  
  138.           POP     DS
  139.           MOV     SP,BP                ; CLEAN UP STACK AND LEAVE
  140.           POP     BP                   ; RESTORE CALLER'S BP
  141.  
  142.           RET     10
  143.  
  144. STICK     ENDP
  145. CODE      ENDS
  146.           END
  147.